﻿using CMS.Constants;
using CMS.Controls.Events;
using CMS.Infos;
using CMS.REST;
using CMS.Util;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;

namespace CMS.Dialogs
{
    public partial class ScheduleAdvisor : Form
    {
        #region 私有字段
        /// <summary>
        /// 上一次发起请求时的使用的查询周次
        /// </summary>
        private uint _ClassWeek = 0;

        /// <summary>
        /// 上一次发起请求是使用查询节次
        /// </summary>
        private uint _ClassTime = 0;
        #endregion

        /// <summary>
        /// 当前选择学期
        /// </summary>
        public Term CurTerm { get; set; } = new Term();

        /// <summary>
        /// 选择了一个房间
        /// </summary>
        public event EventHandler<CreateCourseEventArgs> CreateCourse;

        public ScheduleAdvisor()
        {
            InitializeComponent();

            CB_Week.DataSource = Constant.WeekMap;
            CB_Week.DisplayMember = "Key";
            CB_Week.ValueMember = "Value";
        }

        private void RefreshData()
        {
            RESTResponse response = RESTClient.HttpGetManaged("apis/v1/building_names");
            if (response.IsSuccess)
            {
                CB_Building.BeginUpdate();
                CB_Building.Items.Clear();
                CB_Building.Items.AddRange(response.Data.ToObject<string[]>());
                CB_Building.EndUpdate();
            }
            else
            {
                CB_Building.Items.Clear();
            }
        }


        private class ScheduleAdvisorResult
        {
            /// <summary>
            /// 课室名
            /// </summary>
            [JsonProperty(PropertyName = "room")]
            public string Room { get; set; }

            /// <summary>
            /// 匹配率
            /// </summary>
            [JsonProperty(PropertyName = "ratio")]
            public int Ratio { get; set; }
        }

        /// <summary>
        /// 从服务器上搜索数据
        /// </summary>
        /// <param name="week"></param>
        /// <param name="classWeek"></param>
        /// <param name="classTime"></param>
        /// <param name="building"></param>
        /// <returns></returns>
        private ScheduleAdvisorResult[] GetData(int week, uint classWeek, uint classTime, string building)
        {
            RESTResponse response = RESTClient.HttpGetManaged("apis/v1/schedule_advise", new Dictionary<string, string> {
                {"term_id",CurTerm.ID.ToString() },
                { "week",week.ToString()},
                {"class_week",classWeek.ToString() },
                { "class_time",classTime.ToString()},
                { "building",building}
            });
            if (response.IsSuccess)
            {
                return response.Data.ToObject<ScheduleAdvisorResult[]>();
            }
            else
            {
                MessageBox.Show(this, "获取数据发生错误:" + response.ErrMsg);
                return new ScheduleAdvisorResult[0];
            }
        }

        private Font _HeadFont = new Font("微软雅黑", 12, FontStyle.Bold);
        private Font _ItemFont = new Font("微软雅黑", 8);


        private ListViewItem GenListViewItem(ScheduleAdvisorResult scheduleAdvisor)
        {
            ListViewItem lvi = new ListViewItem
            {
                Text = scheduleAdvisor.Room,
                ImageKey = "Course",
                ForeColor = Color.DarkBlue,
                UseItemStyleForSubItems = false,
                Font = _HeadFont,
                Tag = scheduleAdvisor.Room
            };
            lvi.SubItems.Add(new ListViewItem.ListViewSubItem(lvi, $"匹配率:{scheduleAdvisor.Ratio}%") { Name = "ratio", Font = _ItemFont });
            return lvi;
        }


        private void Bn_Search_Click(object sender, EventArgs e)
        {
            if (CB_Week.SelectedIndex == -1)
            {
                MessageBox.Show(this, "必须选择星期后才能进行筛选", "错误");
                return;
            }

            if (CB_Building.SelectedIndex == -1)
            {
                MessageBox.Show(this, "必须选择查找范围后才能进行筛选", "错误");
                return;
            }

            try
            {
                ushort week = (ushort)CB_Week.SelectedValue;
                string building = (string)CB_Building.SelectedItem;
                _ClassWeek = Utils.ConvertValue(TB_ClassWeek.Text);
                _ClassTime = Utils.ConvertValue(TB_ClassTime.Text);

                ScheduleAdvisorResult[] data = GetData(week, _ClassWeek, _ClassTime, building);
                LV_Result.BeginUpdate();
                LV_Result.Items.Clear();
                foreach (ScheduleAdvisorResult item in data)
                {
                    LV_Result.Items.Add(GenListViewItem(item));
                }
                LV_Result.EndUpdate();
            }
            catch (Exception err)
            {
                MessageBox.Show(this, "查询的过程中发生错误:" + err.Message);
            }
        }

        private void ScheduleAdvisor_Load(object sender, EventArgs e)
        {
            RefreshData();
        }

        private void TB_ClassTime_Enter(object sender, EventArgs e)
        {
            TB_ClassTime.SelectAll();
        }

        private void TB_ClassWeek_Validating(object sender, CancelEventArgs e)
        {
            if (Utils.ValidateTime(TB_ClassWeek.Text))
            {
                PB_Validate1.Image = Resource1.Right16;
            }
            else
            {
                PB_Validate1.Image = Resource1.Wrong16;
                e.Cancel = true;
            }
        }

        private void TB_ClassTime_Validating(object sender, CancelEventArgs e)
        {
            if (Utils.ValidateTime(TB_ClassTime.Text))
            {
                PB_Validate2.Image = Resource1.Right16;
            }
            else
            {
                PB_Validate2.Image = Resource1.Wrong16;
                e.Cancel = true;
            }
        }

        private void LV_Result_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            if (LV_Result.SelectedItems.Count == 1)
            {
                CreateCourse?.Invoke(this, new CreateCourseEventArgs(LV_Result.SelectedItems[0].Tag as string, (ushort)CB_Week.SelectedValue,_ClassWeek,_ClassTime));
            }
        }
    }
}
